﻿using HECore.ServiceFrame.Models;
using HECore.ServiceFrame.Redis;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace HECore.ServiceFrame.Attributes
{
    /// <summary>
    /// 员工鉴权
    /// </summary>
    public class EmoloyeeAuthorizeAttribute : TypeFilterAttribute
    {
        /// <summary>
        /// 权限
        /// </summary>
        public readonly string[] Permissions;

        /// <summary>
        /// 权限
        /// </summary>
        /// <param name="Permissions"></param>
        public EmoloyeeAuthorizeAttribute(params string[] Permissions) : base(typeof(EmoloyeeAuthorizeFilter))
        {
            this.Permissions = Permissions;
        }
    }

    /// <summary>
    /// 员工鉴权
    /// </summary>
    public class EmoloyeeAuthorizeFilter : IAuthorizationFilter
    {
        private readonly FrameRedisClient _redisClient;
        private readonly CurrentEmployee _currentEmployee;

        /// <summary>
        /// 依赖注入
        /// </summary>
        public EmoloyeeAuthorizeFilter(FrameRedisClient redisClient, CurrentEmployee currentEmployee)
        {
            _redisClient = redisClient;
            _currentEmployee = currentEmployee;
        }

        /// <summary>
        /// 验证权限
        /// </summary>
        /// <param name="context"></param>
        public void OnAuthorization(AuthorizationFilterContext context)
        {
            var Headers = context.HttpContext.Request.Headers;
            if (Headers.ContainsKey("token"))
            {
                var token = Headers["token"].ToString();
                if (string.IsNullOrEmpty(token))
                {
                    //未授权，需要登录
                    context.Result = new ContentResult
                    {
                        StatusCode = (int)HttpStatusCode.Unauthorized,
                        ContentType = "application/json;charset=utf-8",
                        Content = JsonConvert.SerializeObject(new ResultContent
                        {
                            Status = (int)HttpStatusCode.Unauthorized,
                            Code = "token.invalid",
                            Title = "登录已失效,请重新登录",
                            Describe = "未传递登录凭证"
                        })
                    };
                }
                else
                {
                    var isExisTokenKey =  _redisClient.KeyExists($"emoloyee:login:token:{token}");
                    if (isExisTokenKey)
                    {
                        // 获取并设置当前登录员工信息
                        var LoginEmployee = _redisClient.StringGet($"emoloyee:login:token:{token}");
                        var LoginEmployeeObject = JsonConvert.DeserializeObject<CurrentEmployee>(LoginEmployee);
                        _currentEmployee.AccountId = LoginEmployeeObject.AccountId;
                        _currentEmployee.TenantId = LoginEmployeeObject.TenantId;
                        _currentEmployee.TenantName = LoginEmployeeObject.TenantName;
                        _currentEmployee.EmployeeId = LoginEmployeeObject.EmployeeId;
                        _currentEmployee.EmployeeFullName = LoginEmployeeObject.EmployeeFullName;
                        _currentEmployee.IsAdministrator = LoginEmployeeObject.IsAdministrator;
                        _currentEmployee.EmployeePermissions = LoginEmployeeObject.EmployeePermissions;

                        // 判断是否需要权限验证
                        var EmoloyeeAuthorize = context.ActionDescriptor.FilterDescriptors
                            .Where(filterDescriptor => filterDescriptor.Scope == FilterScope.Action)
                            .Select(filterDescriptor => filterDescriptor.Filter)
                            .OfType<EmoloyeeAuthorizeAttribute>()
                            .FirstOrDefault();
                        if (EmoloyeeAuthorize != null)
                        {
                            var Permissions = EmoloyeeAuthorize.Permissions;
                            if (Permissions.Any())
                            {
                                if (_currentEmployee.EmployeePermissions.Any())
                                {
                                    bool IsAuthorization = false;
                                    if (_currentEmployee.EmployeePermissions.Any())
                                    {
                                        foreach (var Permission in Permissions)
                                        {
                                            if (_currentEmployee.EmployeePermissions.Where(x => x == Permission).Count() > 0)
                                            {
                                                IsAuthorization = true;
                                                break;
                                            }
                                        }
                                    }
                                    if (IsAuthorization == false)
                                    {
                                        //没有权限
                                        context.Result = new ContentResult
                                        {
                                            StatusCode = (int)HttpStatusCode.Forbidden,
                                            ContentType = "application/json;charset=utf-8",
                                            Content = JsonConvert.SerializeObject(new ResultContent
                                            {
                                                Status = (int)HttpStatusCode.Forbidden,
                                                Code = "no.permission",
                                                Title = "无权限访问",
                                                Describe = "无权限访问，需要权限：" + string.Join("或", Permissions)
                                            })
                                        };
                                    }
                                }
                                else
                                {
                                    //没有权限
                                    context.Result = new ContentResult
                                    {
                                        StatusCode = (int)HttpStatusCode.Forbidden,
                                        ContentType = "application/json;charset=utf-8",
                                        Content = JsonConvert.SerializeObject(new ResultContent
                                        {
                                            Status = (int)HttpStatusCode.Forbidden,
                                            Code = "no.permission",
                                            Title = "无权限访问",
                                            Describe = "无权限访问，需要权限：" + string.Join("或", Permissions)
                                        })
                                    };
                                }
                            }
                        }
                    }
                    else
                    {
                        //无效的token
                        context.Result = new ContentResult
                        {
                            StatusCode = (int)HttpStatusCode.Unauthorized,
                            ContentType = "application/json;charset=utf-8",
                            Content = JsonConvert.SerializeObject(new ResultContent
                            {
                                Status = (int)HttpStatusCode.Unauthorized,
                                Code = "token.invalid",
                                Title = "登录已失效,请重新登录",
                                Describe = "无效的登录凭证"
                            })
                        };
                    }
                }
            }
            else
            {
                //未授权，需要登录
                context.Result = new ContentResult
                {
                    StatusCode = (int)HttpStatusCode.Unauthorized,
                    ContentType = "application/json;charset=utf-8",
                    Content = JsonConvert.SerializeObject(new ResultContent
                    {
                        Status = (int)HttpStatusCode.Unauthorized,
                        Code = "token.invalid",
                        Title = "登录已失效,请重新登录",
                        Describe = "未传递登录凭证"
                    })
                };
            }
        }
    }
}
